import { useState, useEffect, useRef } from 'react'
import moment from 'moment-timezone'
import useStorage from '@/utils/useStorage'

interface UseCountDownProps {
  initCount?: number | null // seconds
  resetOnMount?: boolean
  id?: string // 倒數的id (selfCounting true 時要帶) (必須 unique)
}

interface UseCountDownReturn {
  countNum: number
  isPassed: boolean
  setCountDownSec: (seconds: number) => void
}

export function useCountDown({
  initCount = null,
  resetOnMount = false,
  id = '',
}: UseCountDownProps): UseCountDownReturn {
  const { setItem, getItem, removeItem } = useStorage()

  const selfCounterRef = useRef<NodeJS.Timeout | null>(null)
  const [countNum, setCountNum] = useState<number | null>(null)
  const [endTime, setEndTime] = useState<string | null>(null)

  const isPassed = countNum === null || countNum <= 0

  const setCountDownSec = (seconds: number) => {
    const timeStr = moment().add(seconds, 'seconds').format()
    setEndTime(timeStr)
    setItem(`vshop_${id}_countdown`, timeStr, 'session')
  }

  useEffect(() => {
    const countdownStr = getItem(`vshop_${id}_countdown`, 'session')
    if (!initCount) {
      if (!countdownStr) return
      return setEndTime(countdownStr)
    }
    if (resetOnMount || !countdownStr) return setCountDownSec(initCount)
    setEndTime(countdownStr)
  }, [initCount])

  useEffect(() => {
    if (!endTime) return
    if (selfCounterRef.current) clearInterval(selfCounterRef.current)

    const initCountDownObj = moment.duration(moment(endTime).diff(moment()))
    const msecVal = initCountDownObj.asMilliseconds()

    if (msecVal <= 0) {
      setCountNum(0)
      return
    }

    setCountNum(msecVal)

    selfCounterRef.current = setInterval(() => {
      setCountNum((prevMsec) => (prevMsec !== null ? prevMsec - 1000 : 0))
    }, 1000)

    return () => {
      if (selfCounterRef.current) clearInterval(selfCounterRef.current)
      if (resetOnMount) removeItem(`vshop_${id}_countdown`, 'session')
    }
  }, [endTime])

  useEffect(() => {
    if (countNum === null) return
    if (countNum <= 0) {
      removeItem(`vshop_${id}_countdown`, 'session')
      setCountNum(null)
      if (selfCounterRef.current) clearInterval(selfCounterRef.current)
    }
  }, [countNum])

  return {
    countNum: countNum !== null && countNum >= 0 ? countNum : 0,
    isPassed,
    setCountDownSec,
  }
}
